import cv2
import numpy as np
from PIL import Image


def cv2PIL(image):
    """opencv和 pil的格式转换"""
    return Image.fromarray(cv2.cvtColor(image, cv2.COLOR_BGRA2RGBA))


def PIL2cv(image):
    """opencv和 pil的格式转换"""
    return cv2.cvtColor(np.asarray(image), cv2.COLOR_RGBA2BGR)


def get_bounding_rect(image: np.ndarray) -> np.ndarray:
    """找到最大轮廓的最小矩形"""
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    edges = cv2.Canny(gray, 1, 225)
    contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

    # 找到轮廓中最大面积的然后返回
    max_area = 0
    index = None
    for i, cnt in enumerate(contours):
        x, y, w, h = cv2.boundingRect(cnt)
        area = w * h
        if area > max_area:
            max_area = area
            index = i

    if index is not None:
        x, y, w, h = cv2.boundingRect(contours[index])
        return image[y:y + h, x:x + w, :]
    return image


def get_background_rect(size=(800, 800), color=(255, 255, 255)) -> np.ndarray:
    """生成一个指定大小的图片背景"""
    background = np.ones((size[1], size[0], 3), dtype=np.uint8)
    background[:, :, 0] = color[0]  # 蓝色通道B
    background[:, :, 1] = color[1]  # 绿色通道G
    background[:, :, 2] = color[2]  # 红色通道R
    return background


def combine_image(image: np.ndarray, background: np.ndarray, position=(0, 0), mask=None) -> np.ndarray:
    """背景和指定图片合成在指定位置"""
    ref_image = cv2PIL(image)
    if mask:
        mask = ref_image
    background_image = cv2PIL(background).convert("RGBA")
    background_image.paste(ref_image, box=(
        position[0], position[1], position[0] + ref_image.size[0], position[1] + ref_image.size[1]), mask=mask)
    return PIL2cv(background_image)


def scale_image(image: np.ndarray, max_size) -> np.ndarray:
    """根据最大宽度放缩图像"""
    h, w, n = image.shape
    if h > w:
        resize = (int(max_size * w / h), int(max_size))
    else:
        resize = (int(max_size), int(max_size * h / w))
    return cv2.resize(image, resize)


def save_filename(image, filename) -> str:
    """保存图片为路径"""
    if isinstance(image, Image.Image):
        image.save(filename)
    elif isinstance(image, np.ndarray):
        cv2.imencode(".png", image)[1].tofile(filename)
